package com.heima.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.heima.common.dto.ResponseResult;
import com.heima.common.dto.User;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.util.AppJwtUtil;
import com.heima.common.util.AppThreadLocalUtil;
import com.heima.user.dto.ApAuthor;
import com.heima.user.dto.LoginDto;
import com.heima.user.dto.UserRelationDto;
import com.heima.user.entity.ApUser;
import com.heima.user.entity.ApUserFollow;
import com.heima.user.feign.ArticleClient;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.IApUserFollowService;
import com.heima.user.service.IApUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * APP用户信息表 服务实现类
 * </p>
 *
 * @author mcm
 * @since 2022-06-21
 */
@Service
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements IApUserService {

    /**
     * app登录
     * @param dto
     * @return
     */
    @Override
    public ResponseResult login(LoginDto dto) {
        //关键数据校验 如果设备id 手机号密码都为空 提示参数无效
        if (dto == null || (
                StringUtils.isEmpty(dto.getPhone()) && StringUtils.isEmpty(dto.getPassword()) && StringUtils.isEmpty(dto.getEquipmentId()))
                ) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //手机号密码不为空 使用手机号密码登录
        if (! StringUtils.isEmpty(dto.getPhone()) && !StringUtils.isEmpty(dto.getPassword())){
            //不为空👇
            LambdaQueryWrapper<ApUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ApUser::getPhone,dto.getPhone());
            ApUser one = this.getOne(queryWrapper);
            //通过账号 查询数据库的对象返回 看看对象是否存在 不存在继续抛异常
            if (StringUtils.isEmpty(one)){
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
            }

            //存在的话 获取数据这个对象的密码
            String password = one.getPassword();
            String password1 = dto.getPassword();
            //通过输入的密码 123456 获取到查询出来的对象的salt
            String salt = one.getSalt();
            //拼接 通过MD5加密
            String sum = password1 + salt;
            String md5DigestAsHex = DigestUtils.md5DigestAsHex(sum.getBytes());
            //判断前后端密码是否相同
            if (! md5DigestAsHex.equals(password)){
                //不相同抛异常
                return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
            }

            //相同就去创建token
            HashMap<String, Object> map = new HashMap<>();
            map.put("id",one.getId());
            String token = AppJwtUtil.getToken(map);
            //存放用户ID 👈 token中
            //ResponseResult.ok(Map)   Map = "user",获取数据这个对象的密码 Map = "token",/相通就去创建token
            HashMap<Object, Object> response = new HashMap<>();
            //隐藏用户的敏感信息
            one.setPassword(null);
            one.setSalt(null);
            response.put("user",one);
            response.put("token",token);
            //ResponseResult.ok(👆map)
            return ResponseResult.okResult(response);
        }
        //游客身份登录 为了让请求通过网关 默认使用0作为id生成token
        if (! StringUtils.isEmpty(dto.getEquipmentId())){
            Map<String, Object> userMap = new HashMap<>();
            userMap.put("userId" ,"0");
            String token = AppJwtUtil.getToken(userMap);
            //给前端返回定义好的格式
            Map<String ,Object> map = new HashMap<>();
            map.put("token",token);
            return ResponseResult.okResult(map);
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
    }


    @Autowired
    private ArticleClient articleClient;

    @Autowired
    private IApUserFollowService followService;

    /**
     * 用户关注
     * @param dto
     * @return
     */
    @Override
    public ResponseResult follow(UserRelationDto dto) {
        //判断用户是否登录
        User user = AppThreadLocalUtil.get();
        if (user == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //构建ApUserFollow
        ApUserFollow userFollow = new ApUserFollow();
        userFollow.setUserId(user.getUserId());
        //查询apUser
        ApUser apUser = this.getById(user.getUserId());
        userFollow.setUserName(apUser.getName());
        //根据作者id查询作者信息
        ResponseResult<ApAuthor> responseResult = articleClient.getAuthorById(dto.getAuthorId());
        if (responseResult.getCode().equals(AppHttpCodeEnum.SUCCESS.getCode())){
            ApAuthor author = responseResult.getData();
            if (author != null){
                //获取作者对应的ap_user id
                userFollow.setFollowId(author.getUserId());
                userFollow.setFollowName(author.getName());
            }
        }
        userFollow.setLevel(1);
        userFollow.setCreatedTime(new Date());
        //判断用户是否已经添加过该作者的关注记录
        LambdaQueryWrapper<ApUserFollow> query = new LambdaQueryWrapper<>();
        query.eq(ApUserFollow::getUserId,userFollow.getUserId());
        query.eq(ApUserFollow::getFollowId,userFollow.getFollowId());
        ApUserFollow one = followService.getOne(query);
        //如果没有的话 新增关注记录
        if (one == null){
            if (dto.getOperation() ==0){
                followService.save(userFollow);
            }
        }else {
            //如果是取消关注 删除关注记录
            if (dto.getOperation() == 1){
                followService.remove(query);
            }
        }
        return ResponseResult.okResult();

    }
}
